package turtle.system.doug.SVMSystem;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Properties;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import turtle.system.pt.Bar;
import turtle.system.pt.BarSet;
import turtle.system.pt.DailyStopProfitExec;
import turtle.system.pt.MDD;
import turtle.system.pt.PriceData;
import turtle.system.pt.StatCalc;
import arbor.mining.algorithm.svm.*;

/**
 * 實驗出場訊號出現時,開盤or收盤出場條件
 * 目前用svm來train
 * @author doug
 *
 */
public class PriceDataSVMSystem {
	/*SUPPORT_OUT_INDAY=true,系統將印出出場時反向訊號資料,當沖用*/
    public static final boolean SUPPORT_OUT_INDAY = true;
    public static final int HALF_FORCE_STOP_LOSS = 100;
    /*如果DEFAULT_OUT_INDAY為true,則一定印出反向當沖資料,如果useSVM=true,則此訊號
     * 由SVM決定之*/
    public static final boolean DEFAULT_OUT_INDAY = true; 
    
    public static final boolean[] DEFAULT_START_OR_NOT = new boolean[] {false, false,false, true,true,true}; 
    
    /*writeSVMInput=true將output SVM所需之training data, 也可以觀查到百分之百正確處理出場時間,可獲利的獲利值(optimal profit)*/
    /*十年來最佳profit值,可到44970!!*/
    public boolean trainSVM = false;
    
    public boolean useSVM = !trainSVM;
    //public boolean[] useSVMModel = new boolean[] {false, false, true, false, true, true};
    public boolean[] useSVMModel = new boolean[] {false, false, false, false, false, false};
    //public boolean[] useSVMModel = new boolean[] {true, true, true, true, true, true};
    
    public String scaleSVMFileSuffix = ".range";
    public String modelSVMFileSuffix = ".model";
    public int[]    svmPositiveCount = new int[6];
    public int[]    svmAllCount = new int[6];
    public String[] svmFilePrefix = new String[]  {"data/svm/stoplossLong.svm",
    		                                          "data/svm/stoplossShort.svm",
    		                                          "data/svm/stopprofitLong.svm",
    		                                          "data/svm/stopprofitShort.svm",
    		                                          "data/svm/trendReverseLong.svm",
    		                                          "data/svm/trendReverseShort.svm"    		                                                           
    };
    public BufferedWriter[] svmInput= new BufferedWriter[6];
    
	public static final int STRATEGY_CONSERVATIVE = 1;
	public static final int STRATEGY_POSITIVE = 2;
	public static final String CONS_FN = "data/conservative_my.log";
	public static final String POSI_FN = "data/positive_my.log";
	public String finalSuggestion = null;
	public String summary = null;
	private BufferedWriter writer;
	private static Logger DEFAULT_LOGGER = loadDefaultLogger();
	public Logger logger = DEFAULT_LOGGER;

	// private static String DATA_PATH = "data/";

	// private static String FILENAME_SUFFIX = ".txt";
	private static boolean IS_GENERATE_GRID_CSV = false; // 產生累積獲利 CSV 檔 // 約需執行
	private static boolean IS_PRINT_TURTLE_ACTION = true; // 印出每筆進出場記錄
	private static boolean IS_PRINT_TURTLE_SUMMARY = true; // 印出累積獲利摘要統計
	// private static boolean IS_PRINT_TURTLE_ACTION = false; // 印出每筆進出場記錄

	// 5 分鐘
	// private static boolean IS_GENERATE_GRID_CSV = true; // 產生累積獲利 CSV 檔 //
	// 約需執行 5 分鐘
	/**
	 * 系統強制平倉點數
	 */
	public static int FORCE_STOPLOSS = 100000;
	public static int MAX_DAY_INHAND = 10000;
	public static double MAX_KEEP_INHAND_PERCENTAGE = 0.8;
	public static int FORCE_STOPLOSS_CONSERVATIVE = 300;
	public static int FORCE_STOPLOSS_POSITIVE = 200;
	private static int SCALE_DOWN_FACTOR = 100; // 獲利 CSV 檔中數值除以此常數，方便作圖
	// private static int[] LOSS_STOP_RANGE_FOR_LONG = {27,27}; // 做多停損點數實驗區間
	// private static int[] LOSS_STOP_RANGE_FOR_LONG = { 10, 90 }; // 做多停損點數實驗區間
	public static int[] LOSS_STOP_RANGE_FOR_LONG = null;
	public static int[] LOSS_STOP_RANGE_FOR_LONG_CONSERVATIVE = { 30, 30 }; // 做多停損點數實驗區間
	public static int[] LOSS_STOP_RANGE_FOR_LONG_POSITIVE = { 24, 24 }; // 做多停損點數實驗區間

	public static int[] PROFIT_STOP_RANGE_FOR_LONG = null;
	public static int[] PROFIT_STOP_RANGE_FOR_LONG_CONSERVATIVE = { 195, 195 }; // 做多停利點數實驗區間
	public static int[] PROFIT_STOP_RANGE_FOR_LONG_POSITIVE = { 200, 200 }; // 做多停利點數實驗區間

	// private static int[] LOSS_STOP_RANGE_FOR_SHORT = {27,27}; // 做空停損點數實驗區間
	// private static int[] LOSS_STOP_RANGE_FOR_SHORT = { 10, 90 }; //
	// 做空停損點數實驗區間
	public static int[] LOSS_STOP_RANGE_FOR_SHORT = null;
	public static int[] LOSS_STOP_RANGE_FOR_SHORT_CONSERVATIVE = { 55, 55 }; // 做空停損點數實驗區間
	public static int[] LOSS_STOP_RANGE_FOR_SHORT_POSITIVE = { 14, 14 }; // 做空停損點數實驗區間

	public static int[] PROFIT_STOP_RANGE_FOR_SHORT = null;
	public static int[] PROFIT_STOP_RANGE_FOR_SHORT_CONSERVATIVE = { 170, 170 }; // 做空停利點數實驗區間
	public static int[] PROFIT_STOP_RANGE_FOR_SHORT_POSITIVE = { 125, 125 }; // 做空停利點數實驗區間

	public int numOutStopProfit = 0, numOutStopLoss = 0,
			numOutTrendReverse = 0, numOutForceStopLoss = 0,
			numOutKeepProfit = 0;
			
	// int minDaysIn = 1, maxDaysIn = 100, minDaysOut = 1, maxDaysOut = 100;
	private static int minDaysInForLong = 2, maxDaysInForLong = 3,
			minDaysOutForLong = 2, maxDaysOutForLong = 3;
	private static int minDaysInForShort = 2, maxDaysInForShort = 3,
			minDaysOutForShort = 2, maxDaysOutForShort = 3;

	public static int[][] inAndOut = null;
	public static int[][] inAndOut_CONSERVATIVE = new int[][] { // 特別觀察組合
		{ 2, 9, 2, 5 } };	
		
	public static int[][] inAndOut_POSITIVE = new int[][] { // 特別觀察組合
	{ 3, 9, 2, 6 } };
	
	public String getFinalSuggestion() {	
		if (suggestList.size()>4 && SUPPORT_OUT_INDAY) {
			finalSuggestion = suggestList.get(suggestList.size()-1)+"\n"+
			                  suggestList.get(suggestList.size()-2)+"\n"+
			                  suggestList.get(suggestList.size()-3)+"\n"+
			                  suggestList.get(suggestList.size()-4);		     
		}
		else {
			finalSuggestion = suggestList.get(suggestList.size()-1);
		}
		return finalSuggestion;
	}

	public String getSummary() {
		return summary;
	}

	public PriceDataSVMSystem(int strategyType, String BASE_FILENAME,
			String TX_FILENAME) throws IOException {
		if (strategyType == STRATEGY_POSITIVE) {
			LOSS_STOP_RANGE_FOR_LONG = LOSS_STOP_RANGE_FOR_LONG_POSITIVE;
			LOSS_STOP_RANGE_FOR_SHORT = LOSS_STOP_RANGE_FOR_SHORT_POSITIVE;
			inAndOut = inAndOut_POSITIVE;
			PROFIT_STOP_RANGE_FOR_LONG = PROFIT_STOP_RANGE_FOR_LONG_POSITIVE;
			PROFIT_STOP_RANGE_FOR_SHORT = PROFIT_STOP_RANGE_FOR_SHORT_POSITIVE;
			FORCE_STOPLOSS = FORCE_STOPLOSS_POSITIVE;
			writer = new BufferedWriter(new FileWriter(POSI_FN));
		} else {
			LOSS_STOP_RANGE_FOR_LONG = LOSS_STOP_RANGE_FOR_LONG_CONSERVATIVE;
			LOSS_STOP_RANGE_FOR_SHORT = LOSS_STOP_RANGE_FOR_SHORT_CONSERVATIVE;
			inAndOut = inAndOut_CONSERVATIVE;
			PROFIT_STOP_RANGE_FOR_LONG = PROFIT_STOP_RANGE_FOR_LONG_CONSERVATIVE;
			PROFIT_STOP_RANGE_FOR_SHORT = PROFIT_STOP_RANGE_FOR_SHORT_CONSERVATIVE;
			FORCE_STOPLOSS = FORCE_STOPLOSS_CONSERVATIVE;
			writer = new BufferedWriter(new FileWriter(CONS_FN));
		}

		DateFormat df = new SimpleDateFormat("yyyyMMdd");
		Date today = GregorianCalendar.getInstance().getTime();
		BarSet.ADX_ATTACH = true;
		
		if (trainSVM) {
			for (int i=0;i<6;i++) {
				svmInput[i] = new BufferedWriter(new FileWriter(svmFilePrefix[i]));
			}
		}
		
		long startTime = System.currentTimeMillis();

		String filename = BASE_FILENAME;

		FileReader reader = new FileReader(filename);
		BarSet barSet = new BarSet(reader);
		// Chart.draw(barSet);

		String filename2 = TX_FILENAME;
		FileReader reader2 = new FileReader(filename2);
		BarSet barSet2 = new BarSet(reader2);

		
		SVMWriter sWriter = new SVMWriter("tmp/allsvm.svm","tmp/allsvm.test");
		sWriter.writerSVM(barSet, barSet2);
		
		// print day records in which range is over 300
		// bigRange(barSet, 300);

		int maxProfitDaysInForLong = 0, maxProfitDaysOutForLong = 0, maxProfitDaysInForShort = 0, maxProfitDaysOutForShort = 0, maxProfitLossStopForLong = LOSS_STOP_RANGE_FOR_LONG[0], maxProfitLossStopForShort = LOSS_STOP_RANGE_FOR_SHORT[0], maxProfitProfitStopForLong = PROFIT_STOP_RANGE_FOR_LONG[0], maxProfitProfitStopForShort = PROFIT_STOP_RANGE_FOR_SHORT[0];
		// csv file for Excel graphing
		if (IS_GENERATE_GRID_CSV) {
			BufferedWriter csvOut = new BufferedWriter(new FileWriter(
					"data/parameter.csv"));
			StringBuilder sb = new StringBuilder();
			StringBuffer buf = new StringBuffer();
			StatCalc scStrategyProfit = new StatCalc(); // 記錄所有進出天數組合的獲利

			int kStep = 7;
			int qStep = 7;
			int oStep = 20;
			int pStep = 20;
			for (int k = LOSS_STOP_RANGE_FOR_LONG[0]; k <= LOSS_STOP_RANGE_FOR_LONG[1]; k += kStep) {
				for (int q = LOSS_STOP_RANGE_FOR_SHORT[0]; q <= LOSS_STOP_RANGE_FOR_SHORT[1]; q += qStep) {
					for (int o = PROFIT_STOP_RANGE_FOR_LONG[0]; o <= PROFIT_STOP_RANGE_FOR_LONG[1]; o += oStep) {
						for (int p = PROFIT_STOP_RANGE_FOR_SHORT[0]; p <= PROFIT_STOP_RANGE_FOR_SHORT[1]; p += pStep) {
							StatCalc stopStrategy = new StatCalc(); // 記錄所有進出天數組合的獲利

							for (int i = minDaysInForLong; i <= maxDaysInForLong; i++) {
								for (int j = minDaysOutForLong; j <= maxDaysOutForLong; j++) {
									for (int m = minDaysInForShort; m <= maxDaysInForShort; m++) {
										for (int n = minDaysOutForShort; n <= maxDaysOutForShort; n++) {

											double profit = turtle(barSet, i,
													j, m, n, k, q, o, p,
													barSet2);
											scStrategyProfit.enter(profit,
													new int[] { i, j, m, n, k,
															q, o, p });
											stopStrategy.enter(profit,
													new int[] { i, j, m, n, k,
															q, o, p });
											// int scaleProfit = (int)(profit /
											// SCALE_DOWN_FACTOR);
											// sb.append(String.format("%d",
											// scaleProfit));
											// if (j != maxDaysOut)
											// sb.append(","); // row end
											// 不加 ,
										}
									}
									System.out.print(".");
								}
							}
							buf
									.append(String
											.format(
													"完成停損%d,%d 停利%d,%d - 最大獲利組合(做多%d,%d)(做空%d,%d)[停%d,%d]=%.2f,最小獲利組合(做多%d,%d)(做空%d,%d)[停%d,%d]=%.2f,平均獲利=%.2f,正獲利組合數=%d(平均%.2f),負獲利組合數=%d(平均%.2f)",
													k,
													q,
													o,
													p,
													stopStrategy.getMaxParam()[0],
													stopStrategy.getMaxParam()[1],
													stopStrategy.getMaxParam()[2],
													stopStrategy.getMaxParam()[3],
													stopStrategy.getMaxParam()[4],
													stopStrategy.getMaxParam()[5],
													stopStrategy.getMax(),
													stopStrategy.getMinParam()[0],
													stopStrategy.getMinParam()[1],
													stopStrategy.getMinParam()[2],
													stopStrategy.getMinParam()[3],
													stopStrategy.getMinParam()[4],
													stopStrategy.getMinParam()[5],
													stopStrategy.getMin(),
													stopStrategy.getMean(),
													stopStrategy
															.getPositiveCount(),
													stopStrategy
															.getPositiveMean(),
													stopStrategy
															.getNegativeCount(),
													stopStrategy
															.getNegativeMean()));
							System.out.println(buf.toString());
							// 完成停損%d,%d 停利%d,%d -
							// 最大獲利組合(做多%d,%d)(做空%d,%d)[停%d,%d]=%.2f,最小獲利組合(做多%d,%d)(做空%d,%d)[停%d,%d]=%.2f,平均獲利=%.2f,正獲利組合數=%d(平均%.2f),負獲利組合數=%d(平均%.2f)
							String outStr = k + "," + q + "," + o + "," + p
									+ "," + stopStrategy.getMaxParam()[0] + ","
									+ stopStrategy.getMaxParam()[1] + ","
									+ stopStrategy.getMaxParam()[2] + ","
									+ stopStrategy.getMaxParam()[3] + ","
									+ stopStrategy.getMaxParam()[4] + ","
									+ stopStrategy.getMaxParam()[5] + ","
									+ stopStrategy.getMax() + ","
									+ stopStrategy.getMinParam()[0] + ","
									+ stopStrategy.getMinParam()[1] + ","
									+ stopStrategy.getMinParam()[2] + ","
									+ stopStrategy.getMinParam()[3] + ","
									+ stopStrategy.getMinParam()[4] + ","
									+ stopStrategy.getMinParam()[5] + ","
									+ stopStrategy.getMin() + ","
									+ stopStrategy.getMean() + ","
									+ stopStrategy.getPositiveCount() + ","
									+ stopStrategy.getPositiveMean() + ","
									+ stopStrategy.getNegativeCount() + ","
									+ stopStrategy.getNegativeMean();
							csvOut.write(outStr + "\n");
							csvOut.flush();
							buf = new StringBuffer();
						}
						// sb.append("\n");
					}
				}
			}
			csvOut.close();
			System.out
					.println(String
							.format(
									"最大獲利組合(做多%d,%d)(做空%d,%d)[停損%d,%d][停利%d,%d]=%.2f,"
											+ "最小獲利組合(做多%d,%d)(做空%d,%d)[停損%d,%d][停利%d,%d]=%.2f,"
											+ "平均獲利=%.2f,正獲利組合數=%d(平均%.2f),負獲利組合數=%d(平均%.2f)",
									scStrategyProfit.getMaxParam()[0],
									scStrategyProfit.getMaxParam()[1],
									scStrategyProfit.getMaxParam()[2],
									scStrategyProfit.getMaxParam()[3],
									scStrategyProfit.getMaxParam()[4],
									scStrategyProfit.getMaxParam()[5],
									scStrategyProfit.getMaxParam()[6],
									scStrategyProfit.getMaxParam()[7],
									scStrategyProfit.getMax(), scStrategyProfit
											.getMinParam()[0], scStrategyProfit
											.getMinParam()[1], scStrategyProfit
											.getMinParam()[2], scStrategyProfit
											.getMinParam()[3], scStrategyProfit
											.getMinParam()[4], scStrategyProfit
											.getMinParam()[5], scStrategyProfit
											.getMinParam()[6], scStrategyProfit
											.getMinParam()[7], scStrategyProfit
											.getMin(), scStrategyProfit
											.getMean(), scStrategyProfit
											.getPositiveCount(),
									scStrategyProfit.getPositiveMean(),
									scStrategyProfit.getNegativeCount(),
									scStrategyProfit.getNegativeMean()));

			maxProfitDaysInForLong = scStrategyProfit.getMaxParam()[0];
			maxProfitDaysOutForLong = scStrategyProfit.getMaxParam()[1];
			maxProfitLossStopForLong = scStrategyProfit.getMaxParam()[2];
			maxProfitLossStopForShort = scStrategyProfit.getMaxParam()[3];
		}

		System.out.println("");
		for (int[] ia : inAndOut) {
			turtle(barSet, ia[0], ia[1], ia[2], ia[3],
					maxProfitLossStopForLong, maxProfitLossStopForShort,
					maxProfitProfitStopForLong, maxProfitProfitStopForShort,
					barSet2);
			System.out.println("");
		}

		// 重新 print 一次最大獲利組合
		/*
		 * if (IS_GENERATE_GRID_CSV) { turtle(barSet, maxProfitDaysInForLong,
		 * maxProfitDaysOutForLong, maxProfitDaysInForShort,
		 * maxProfitDaysOutForShort, maxProfitLossStopForLong,
		 * maxProfitLossStopForShort, maxProfitProfitStopForLong,
		 * maxProfitProfitStopForShort, barSet2); }
		 */
		// Get elapsed time in milliseconds
		long elapsedTimeMillis = System.currentTimeMillis() - startTime;
		System.out.println(String.format("執行時間: %.2f 秒",
				elapsedTimeMillis / 1000F));
		writer.close();
		if (trainSVM) {
			for (int i=0;i<6;i++) {
				svmInput[i].close();
			}
		}
	}

	public static void copyFile(String srcFN, String destFN) {
		try {
			File inputFile = new File(srcFN);
			File outputFile = new File(destFN);

			FileReader in = new FileReader(inputFile);
			FileWriter out = new FileWriter(outputFile);
			int c;

			while ((c = in.read()) != -1)
				out.write(c);

			in.close();
			out.close();
		} catch (IOException e) {
			System.out.println(e);
		}
	}

	public static void bigRange(BarSet barSet, int howBig) {
		ListIterator<Bar> it = barSet.iter();
		int barCountTotal = 0;
		int barCountMatch = 0;
		while (it.hasNext()) {
			Bar bar = it.next();
			barCountTotal++;
			if (bar.range > howBig) {
				System.out.println(bar);
				barCountMatch++;
			}
		}
		System.out.println(String.format("%d out of %d match the criteria",
				barCountMatch, barCountTotal));
	}

	private static int highestIndex(List<Double> list) {
		int ret = 0;
		Iterator<Double> iter = list.iterator();
		double highest = Double.MIN_VALUE;
		int currentIndex = 0;
		while (iter.hasNext()) {
			double currentValue = iter.next();
			if (currentValue > highest) {
				highest = currentValue;
				ret = currentIndex;
			}
			currentIndex++;
		}
		return ret;
	}

	private static int lowestIndex(List<Double> list) {
		int ret = 0;
		Iterator<Double> iter = list.iterator();
		double lowest = Double.MAX_VALUE;
		int currentIndex = 0;
		while (iter.hasNext()) {
			double currentValue = iter.next();
			if (currentValue < lowest) {
				lowest = currentValue;
				ret = currentIndex;
			}
			currentIndex++;
		}
		return ret;
	}

	ArrayList<String> suggestList = new ArrayList<String>();
	private String printTurtleAddAction(Bar bar, Bar bar2, boolean inHand, boolean bull,			
			double baseOrProfit,boolean stopProfit, boolean stopLoss, boolean trendReverse, 
			double liquidPrice, Bar breakBar2, StatCalc scProfit) {
	  StringBuffer buf = new StringBuffer();
	  if (!IS_PRINT_TURTLE_ACTION)
			return null;	  
	  buf.append(bar.mergeBar(bar2) + "\n");
		buf
		.append((inHand ? "當沖進場" : ("當沖出場, 出場價 " + String.format(
				"%.0f", baseOrProfit)))
				+ ", 理由：");
		if (inHand && stopProfit) {
			buf.append("停利出場訊號反向進場");
		}
		else if (!inHand && stopProfit) {
			buf.append("停利出場訊號反向出場");
		}
		if (inHand && stopLoss) {
			buf.append("停損出場訊號反向進場");
		}
		else if (!inHand && stopLoss) {
			buf.append("停損出場訊號反向出場");
		}
		if (inHand && trendReverse) {
			buf.append("趨勢反轉出場訊號反向進場");
		}
		else if (!inHand && trendReverse) {
			buf.append("趨勢反轉出場訊號反向出場");
		}
		
		buf.append(", ");

		if (!inHand) {
		  buf.append(String.format("前一日大盤[%.0f-%.0f-%.0f-%.0f-d=%.0f], ",
				breakBar2.open, breakBar2.high, breakBar2.low, breakBar2.close,
				breakBar2.diff));		
		}
		if (inHand) {
			buf.append("做" + (bull ? "多" : "空") +					
					", 進場價 "
					+ String.format("%.0f", baseOrProfit));
			
		} else {
			buf.append("獲利 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *["
							+ String.format("%.0f](%.0f) * *", liquidPrice,
									scProfit.getSum()));
		}
		try {
			writer.write(buf.toString() + "\n");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		logger.info(buf.toString());		
		System.out.println("=======================================");
		suggestList.add(buf.toString());
	  return buf.toString();
	}
	private String printTurtleAction(Bar bar, boolean inHand, boolean bull,boolean continueTrade,
			double baseOrProfit, int daysInOrOut, boolean stopLoss,
			int lossStop, boolean stopProfit, int profitStop, boolean forceOut,
			boolean keepProfitOut, boolean startOrEndOut,
			double liquidPrice, Bar bar2, Bar breakBar2, StatCalc scProfit) {
		if (!IS_PRINT_TURTLE_ACTION)
			return null;
		StringBuffer buf = new StringBuffer();

		buf.append(bar.mergeBar(bar2) + "\n");
		if (forceOut) {
			if (baseOrProfit == -FORCE_STOPLOSS) {
				buf.append("強制出場, 出場價 " + String.format("%.0f", liquidPrice)
						+ ", 理由：" + "盤中強制停損"+FORCE_STOPLOSS+"出場,");
			} else {
				buf.append("強制出場, 出場價 " + String.format("%.0f", liquidPrice)
						+ ", 理由：" + "盤中開盤強制停損"+FORCE_STOPLOSS+"出場,");
			}
		} 
		else if (keepProfitOut == true)
		{
			buf.append((startOrEndOut?"開盤":"收盤")+"出場, 出場價 " + String.format("%.0f", liquidPrice)
					+ ", 理由：" + "為保獲利出場,");			
		}
		else {
			buf
					.append((inHand ? "開盤進場" :(startOrEndOut?"開盤":"收盤")+ ("出場, 出場價 " + String.format(
							"%.0f", liquidPrice)))
							+ ", 理由："
							+ ((stopLoss | stopProfit) ? ((stopLoss) ? ("停損"
									+ lossStop + " 點    ")
									: ("停利" + profitStop + " 點    "))
									: ("前一日創 " + daysInOrOut + " 天新" + (inHand
											^ bull ? "低" : "高"))) +
											", ");
		}
		buf.append(String.format("前一日大盤[%.0f-%.0f-%.0f-%.0f-d=%.0f], ",
				breakBar2.open, breakBar2.high, breakBar2.low, breakBar2.close,
				breakBar2.diff));
		if (inHand) {
			buf.append("做" + (bull ? "多" : "空") +
					(continueTrade? "(昨單續留)":"")+ 
					", 進場價 "
					+ String.format("%.0f", baseOrProfit)+" (停損價:"+
					String.format("%.0f", baseOrProfit+(bull? -FORCE_STOPLOSS :FORCE_STOPLOSS))		
			+")");
			
		} else {
			buf
					.append("獲利 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *["
							+ String.format("%.0f](%.0f) * *", baseOrProfit,
									scProfit.getSum()));
		}
		try {
			writer.write(buf.toString() + "\n");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		logger.info(buf.toString());
		/*
		 * logger.info(bar.mergeBar(bar2)); buf.append(bar.mergeBar(bar2));
		 * logger.info ((inHand ? "進場" : ("出場, 出場價 " + String.format("%.0f",
		 * liquidPrice))) + ", 理由：" + (stopLoss ? ("停損 " + lossStop + " 點    ")
		 * : ("前一日創 " + daysInOrOut + " 天新" + (inHand ^ bull ? "低" : "高"))) +
		 * ", "); buf.append((inHand ? "進場" : ("出場, 出場價 " +
		 * String.format("%.0f", liquidPrice))) + ", 理由：" + (stopLoss ? ("停損 " +
		 * lossStop + " 點    ") : ("前一日創 " + daysInOrOut + " 天新" + (inHand ^
		 * bull ? "低" : "高"))) + ", ");
		 * logger.info(String.format("前一日[%.0f,%.0f,%.0f,%.0f,d=%.0f], ",
		 * breakBar2.open, breakBar2.high, breakBar2.low, breakBar2.close,
		 * breakBar2.diff));
		 * buf.append(String.format("前一日[%.0f,%.0f,%.0f,%.0f,d=%.0f], ",
		 * breakBar2.open, breakBar2.high, breakBar2.low, breakBar2.close,
		 * breakBar2.diff)); if (inHand) { logger.info("做" + (bull ? "多" : "空")
		 * + ", 進場價 " + String.format("%.0f", baseOrProfit)); buf.append("做" +
		 * (bull ? "多" : "空") + ", 進場價 " + String.format("%.0f", baseOrProfit));
		 * } else {logger.info(
		 * "獲利 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *["
		 * + String.format("%.0f", baseOrProfit) + "] * *");buf.append(
		 * "獲利 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *["
		 * + String.format("%.0f", baseOrProfit) + "] * *"); }
		 */
		System.out.println("=======================================");
		suggestList.add(buf.toString());
		return buf.toString();
	}

	private static int diffCalendarDays(Bar current, Bar base) {
		long diffMillis = current.today.getTimeInMillis()
				- base.today.getTimeInMillis();
		return (int) (diffMillis / (24 * 60 * 60 * 1000));
	}

	StatCalc thisProfit = null;

	public void setProfitStat(StatCalc prof) {
		this.thisProfit = prof;
	}

	public StatCalc getProfitStat() {
		return thisProfit;
	}

	double thisAcc = -1;

	public void setAcc(double acc) {
		this.thisAcc = acc;
	}

	public double getAcc() {
		return this.thisAcc;
	}

	MDD thisMDD = null;

	public void setMDD(MDD mdd) {
		this.thisMDD = mdd;
	}

	public MDD getMDD() {
		return this.thisMDD;
	}

	/**
	 * 強制平倉出場
	 */
	public boolean performInstantlyForceOut(Bar bar2, double basePrice2,
			boolean bull) {

		boolean forceOut = false;
		if (bar2.high >= basePrice2 + FORCE_STOPLOSS // 強制盤中停損
				&& !bull) { // 手上持有 short position
			forceOut = true;
		} else if (bar2.low <= basePrice2 - FORCE_STOPLOSS // 強制盤中停損
				&& bull) { // 手上持有 多單
			forceOut = true;
		}
		return forceOut;
	}

	public double turtle(BarSet barSet, int daysInForLong, int daysOutForLong,
			int daysInForShort, int daysOutForShort, int lossStopForLong,
			int lossStopForShort, int profitStopForLong,
			int profitStopForShort, BarSet barSet2) {

		StatCalc stopLossStat = new StatCalc();
		StatCalc stopProfitStat = new StatCalc();
		StatCalc keepProfitStat = new StatCalc();
		StatCalc stopTrendReverseStat = new StatCalc();
		StatCalc stopForceStopLossStat = new StatCalc();
		StatCalc stopLossOpenCloseStat = new StatCalc();
		StatCalc stopProfitOpenCloseStat = new StatCalc();
		StatCalc stopProfit4BullOpenCloseStat = new StatCalc();

		StatCalc stopProfitSVMIn4ShortStat = new StatCalc();
		StatCalc stopProfitSVMIn4LongStat = new StatCalc();
		StatCalc scSVMSellStrategyProfit = new StatCalc();
		HashMap<String, Integer> tradeMap = new HashMap<String, Integer>();
		HashMap<String, StatCalc> tradeDetailMap = new HashMap<String, StatCalc>();
		String prevTrade = null;
		ListIterator<Bar> it = barSet.iter();
		ListIterator<Bar> it2 = barSet2.iter();
		Bar baseBar = null;
		int baseBarIndex = 0;
		StatCalc scHoldCalendarDays = new StatCalc();
		StatCalc scHoldTransactionDays = new StatCalc();
		StatCalc scProfit = new StatCalc();
		StatCalc scProfitLongDayTrade = new StatCalc();
		StatCalc scProfitShortDayTrade = new StatCalc();
		StatCalc scProfitLongCloseDayTrade = new StatCalc();
		StatCalc scProfitShortCloseDayTrade = new StatCalc();
		StatCalc scProfitStopLossDoubleIn = new StatCalc();
		StatCalc scProfitStopLossPrevDoubleIn = new StatCalc();
		StatCalc scProfitLong = new StatCalc();
		StatCalc scProfitShort = new StatCalc();
		StatCalc maxDrawDown = new StatCalc();

		boolean inHand = false;
		boolean bull = false;
		double basePrice = 0.0;
		double basePrice2 = 0.0;
		double accuProfit = 0.0;
		boolean forceOut = false;
		double maxProfitOneTrade = 0;
        int dayInHand = 0;
        boolean tryContinueTrade = false;
        int prevStopLossAndBull = -1; /*0為空單，１為多單*/
		LinkedList<Double> listHighInForLong = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// high
		// 組成的
		// list，用以評估進場點(做多)
		LinkedList<Double> listLowInForLong = new LinkedList<Double>(); // 以各
		// day
		// bar 的
		// low
		// 組成的
		// list，用以評估進場點(做多)
		LinkedList<Double> listHighOutForLong = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// high
		// 組成的
		// list，用以評估出場點(做多)
		LinkedList<Double> listLowOutForLong = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// low
		// 組成的
		// list，用以評估出場點(做多)
		LinkedList<Double> listCloseInForLong = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// close
		// 組成的
		// list，用以評估進場點(做多)
		LinkedList<Double> listCloseOutForLong = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// close
		// 組成的
		// list，用以評估出場點(做多)

		LinkedList<Double> listHighInForShort = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// high
		// 組成的
		// list，用以評估進場點(做空)
		LinkedList<Double> listLowInForShort = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// low
		// 組成的
		// list，用以評估進場點(做空)
		LinkedList<Double> listHighOutForShort = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// high
		// 組成的
		// list，用以評估出場點(做空)
		LinkedList<Double> listLowOutForShort = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// low
		// 組成的
		// list，用以評估出場點(做空)
		LinkedList<Double> listCloseInForShort = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// close
		// 組成的
		// list，用以評估進場點(做空)
		LinkedList<Double> listCloseOutForShort = new LinkedList<Double>(); // 以各
		// day
		// bar
		// 的
		// close
		// 組成的
		// list，用以評估出場點(做空)
		Bar bar = null;
		Bar bar2 = null;
		while (it.hasNext()) {

			if (forceOut) { // 強制斷頭出場則不必讀取下一筆,因為資料己被讀取過
				forceOut = false;
			} else {
				/* 取得新一天的資料 */
				bar = it.next();
				bar2 = it2.next();
				/* 更新進場點資料 window (做多) */
				if (listHighInForLong.size() == daysInForLong) {
					listHighInForLong.removeFirst();
				}
				if (listLowInForLong.size() == daysInForLong) {
					listLowInForLong.removeFirst();
				}
				if (listCloseInForLong.size() == daysInForLong) {
					listCloseInForLong.removeFirst();
				}
				listHighInForLong.add(bar.high);
				listLowInForLong.add(bar.low);
				listCloseInForLong.add(bar.close);

				/* 更新進場點資料 window (做空) */
				if (listHighInForShort.size() == daysInForShort) {
					listHighInForShort.removeFirst();
				}
				if (listLowInForShort.size() == daysInForShort) {
					listLowInForShort.removeFirst();
				}
				if (listCloseInForShort.size() == daysInForShort) {
					listCloseInForShort.removeFirst();
				}
				listHighInForShort.add(bar.high);
				listLowInForShort.add(bar.low);
				listCloseInForShort.add(bar.close);

				/* 更新出場點資料 window (做多) */
				if (listHighOutForLong.size() == daysOutForLong) {
					listHighOutForLong.removeFirst();
				}
				if (listLowOutForLong.size() == daysOutForLong) {
					listLowOutForLong.removeFirst();
				}
				if (listCloseOutForLong.size() == daysOutForLong) {
					listCloseOutForLong.removeFirst();
				}
				listHighOutForLong.add(bar.high);
				listLowOutForLong.add(bar.low);
				listCloseOutForLong.add(bar.close);

				/* 更新出場點資料 window (做空) */
				if (listHighOutForShort.size() == daysOutForShort) {
					listHighOutForShort.removeFirst();
				}
				if (listLowOutForShort.size() == daysOutForShort) {
					listLowOutForShort.removeFirst();
				}
				if (listCloseOutForShort.size() == daysOutForShort) {
					listCloseOutForShort.removeFirst();
				}
				listHighOutForShort.add(bar.high);
				listLowOutForShort.add(bar.low);
				listCloseOutForShort.add(bar.close);
			}
						
			if (!inHand) { // 目前空手
				if ((listLowInForShort.size() == daysInForShort && lowestIndex(listLowInForShort) == daysInForShort - 1)
						&& (listHighInForLong.size() == daysInForLong && highestIndex(listHighInForLong) == daysInForLong - 1)) { // 盤中
					// 創
					// daysInForShort
					// 天新低且創
					// daysInForLong
					// 天新高(盤中雙向突破）
					// do nothing, 不進場
				} else if (listLowInForShort.size() == daysInForShort
				// && lowestIndex(listHighInForShort) == daysInForShort - 1 //
						// day bar 的 high 創 daysInForShort 天新低
						&& lowestIndex(listLowInForShort) == daysInForShort - 1 // day
				// bar
				// 的
				// low
				// 創
				// daysInForShort
				// 天新低
				// ******
				// 略勝
				// && lowestIndex(listCloseInForShort) == daysInForShort - 1 //
				// day bar 的 close 創 daysInForShort 天新低
				) {
					inHand = true; // (空單)進場
					bull = false; // 建立 short position
					if (prevTrade != null) {
						String d = "空單進場,前單為" + prevTrade;
						if (tradeMap.containsKey(d)) {
							tradeMap.put(d, tradeMap.get(d) + 1);
						} else {
							tradeMap.put(d, 1);
						}
					}
					int nextIndex = it.nextIndex();
					if (nextIndex == barSet.size())
						continue; // 解決在資料尾端會造成 IndexOutOfBoundsException 的問題

					Bar nextBar = barSet.getBar(nextIndex); // 交易 DATA_FILENAME
					Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
					// DATA_FILENAME2
					Bar breakBar2 = barSet.getBar(nextIndex - 1);

					basePrice = nextBar.open; // 假設隔天開盤價成交
					basePrice2 = nextBar2.open; // 假設隔天開盤價成交

					boolean continueTrade = false;
					if (tryContinueTrade && prevStopLossAndBull == 0)
					{
						/*前單為停損出場，但獲利為正,且為同向空單，則前單不出場，續單*/
						scProfit.enter(bar2.close-nextBar2.open);
						continueTrade = true;
					}
					
					/*嘗試在空單進場訊號出場當天再多一單同向進場*/
					{
						if (nextBar2.high -bar2.close > HALF_FORCE_STOP_LOSS)
						{
							scProfitShortDayTrade.enter(-HALF_FORCE_STOP_LOSS);
						}
						else {
							scProfitShortDayTrade.enter(bar2.close - nextBar2.close);
						}
					}		
					
					baseBar = nextBar;
					baseBarIndex = it.nextIndex();
					// printTurtleAction(nextBar, inHand, bull, basePrice,
					// daysIn, false, 0, 0);
					System.out.println("大盤入場參考價:"+basePrice+","+"期貨入場價:"+basePrice2);
					printTurtleAction(nextBar, inHand, bull, continueTrade, basePrice2,
							daysInForShort, false, 0, false, -1, forceOut, false, false, 0,
							nextBar2, breakBar2, scProfit);
					tryContinueTrade = false;
					prevStopLossAndBull = -1;
				} else if (listHighInForLong.size() == daysInForLong
				// && highestIndex(listHighInForLong) == daysInForLong - 1 //
						// day bar 的 high 創 daysInForLong 天新高
						&& highestIndex(listLowInForLong) == daysInForLong - 1 // day
				// bar
				// 的
				// low
				// 創
				// daysInForLong
				// 天新高
				// && highestIndex(listCloseInForLong) == daysInForLong - 1 //
				// day bar 的 close 創 daysInForLong 天新高
				) {
					inHand = true; // 進場
					bull = true; // 建立 long position
					if (prevTrade != null) {
						String d = "多單進場,前單為" + prevTrade;
						if (tradeMap.containsKey(d)) {
							tradeMap.put(d, tradeMap.get(d) + 1);
						} else {
							tradeMap.put(d, 1);
						}
					}
					int nextIndex = it.nextIndex();
					if (nextIndex == barSet.size())
						continue; // 解決在資料尾端會造成 IndexOutOfBoundsException 的問題

					Bar nextBar = barSet.getBar(nextIndex); // 交易 DATA_FILENAME
					Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
					// DATA_FILENAME2
					Bar breakBar2 = barSet.getBar(nextIndex - 1);

					// basePrice = nextBar.open; // 假設隔天開盤價成交 // 判斷進出場價
					basePrice = nextBar.close; // 假設隔天收盤價成交 // 判斷進出場價
					// basePrice2 = nextBar2.close; // 假設隔天收盤價成交 // 實際操作價
					basePrice2 = nextBar2.open; // 假設隔天收盤價成交 // 實際操作價
										
					boolean continueTrade = false;
					if (tryContinueTrade && prevStopLossAndBull == 1)
					{
						/*前單為停損出場，且獲利為正，同向多單，則前單不出場，續單*/
						scProfit.enter(nextBar2.open-bar2.close);
						continueTrade = true;
					}					
					
					
					/*嘗試在多單進場訊號出場當天再多一單同向進場*/
					{
						if (nextBar2.open -nextBar2.low > HALF_FORCE_STOP_LOSS)
						{
							scProfitLongDayTrade.enter(-HALF_FORCE_STOP_LOSS);
						}
						else {
							scProfitLongDayTrade.enter(nextBar2.close - nextBar2.open);
						}
					}
					
					
					baseBar = nextBar;
					baseBarIndex = it.nextIndex();
					System.out.println("大盤入場參考價:"+basePrice+","+"期貨入場價:"+basePrice2);
					printTurtleAction(nextBar, inHand, bull, continueTrade, basePrice2,
							daysInForLong, false, 0, false, -1, forceOut, false, false, 0,
							nextBar2, breakBar2, scProfit);
					tryContinueTrade = false;
					prevStopLossAndBull = -1;
				}
				
				if (!inHand && prevStopLossAndBull!=-1) { /*空手多於一天*/
					tryContinueTrade = false;
				}
			} else { // 目前手上有部位
				if (bar2.high >= basePrice2 + FORCE_STOPLOSS // 強制盤中停損
						&& !bull) { // 手上持有 short position
					forceOut = true;
					inHand = false; // 出場
					this.numOutForceStopLoss++;
					prevTrade = "空單,強制盤中停損出場";
					int nextIndex = it.nextIndex();
					if (nextIndex == barSet.size())
						continue; // 解決在資料尾端會造成 IndexOutOfBoundsException 的問題
					double liquidatePrice2 = basePrice2 + FORCE_STOPLOSS;

					/**
					 * 開盤就要被強迫平倉了
					 */
					if (bar2.open >= basePrice2 + FORCE_STOPLOSS) {
						liquidatePrice2 = bar2.open;
					}
					Bar nextBar = barSet.getBar(nextIndex - 1); // 交易
					// DATA_FILENAME
					Bar nextBar2 = barSet2.getBar(nextIndex - 1); // 交易
					// DATA_FILENAME2
					Bar breakBar2 = barSet.getBar(nextIndex - 2);

					double profit2 = basePrice2 - liquidatePrice2; // 計算獲利
					// accuProfit += profit;
					accuProfit += profit2;
					// scProfit.enter(profit);
					scProfit.enter(profit2);
					if (tradeDetailMap.containsKey(prevTrade)) {
						tradeDetailMap.get(prevTrade).enter(profit2);
					} else {
						StatCalc sc = new StatCalc();
						sc.enter(profit2);
						tradeDetailMap.put(prevTrade, sc);
					}

					stopForceStopLossStat.enter(profit2);
					// scProfitShort.enter(profit);
					scProfitShort.enter(profit2);

					if (IS_PRINT_TURTLE_SUMMARY) {
						scHoldCalendarDays.enter(diffCalendarDays(nextBar,
								baseBar));
						scHoldTransactionDays.enter(it.nextIndex()
								- baseBarIndex);
					}
					printTurtleAction(nextBar, inHand, bull, false, profit2,
							daysOutForShort, false, -1, true,
							profitStopForShort, forceOut, false, false, liquidatePrice2,
							nextBar2, breakBar2, scProfit);
				} else if (bar2.low <= basePrice2 - FORCE_STOPLOSS // 強制盤中停損
						&& bull) { // 手上持有 多單
					forceOut = true;
					inHand = false; // 出場
					this.numOutForceStopLoss++;
					prevTrade = "多單,強制盤中停損出場";
					int nextIndex = it.nextIndex();
					if (nextIndex == barSet.size())
						continue; // 解決在資料尾端會造成 IndexOutOfBoundsException 的問題
					double liquidatePrice2 = basePrice2 - FORCE_STOPLOSS;
					/**
					 * 開盤就要被強迫平倉了
					 */
					if (bar2.open <= basePrice2 - FORCE_STOPLOSS) {
						liquidatePrice2 = bar2.open;
					}
					Bar nextBar = barSet.getBar(nextIndex - 1); // 交易
					// DATA_FILENAME
					Bar nextBar2 = barSet2.getBar(nextIndex - 1); // 交易
					// DATA_FILENAME2
					Bar breakBar2 = barSet.getBar(nextIndex - 2);

					double profit2 = liquidatePrice2 - basePrice2; // 計算獲利
					// accuProfit += profit;
					accuProfit += profit2;
					// scProfit.enter(profit);
					scProfit.enter(profit2);
					if (tradeDetailMap.containsKey(prevTrade)) {
						tradeDetailMap.get(prevTrade).enter(profit2);
					} else {
						StatCalc sc = new StatCalc();
						sc.enter(profit2);
						tradeDetailMap.put(prevTrade, sc);
					}

					stopForceStopLossStat.enter(profit2);
					// scProfitShort.enter(profit);

					scProfitLong.enter(profit2);
					if (IS_PRINT_TURTLE_SUMMARY) {
						scHoldCalendarDays.enter(diffCalendarDays(nextBar,
								baseBar));
						scHoldTransactionDays.enter(it.nextIndex()
								- baseBarIndex);
					}

					// printTurtleAction(nextBar, inHand, bull, profit, daysOut,
					// true, lossStopForShort, liquidatePrice);
					printTurtleAction(nextBar, inHand, bull, false, profit2,
							daysOutForShort, false, -1, true,
							profitStopForShort, forceOut, false,  false, liquidatePrice2,
							nextBar2, breakBar2, scProfit);
				}
			
				else {					
					if (bull) {
						double comp = bar2.high - basePrice2;					
						if (maxProfitOneTrade<comp)
							maxProfitOneTrade = comp;				 
					}
					else { //空單
						double comp =  basePrice2 - bar2.low;					
						if (maxProfitOneTrade<comp)
							maxProfitOneTrade = comp;				 					
					}					
					
					
					/* 以下隔天出場條件,也都可能會有  隔天中途被迫平倉出場.. 
					 * 目前考慮如果昨天已決定今天要出場，如果為盤末出場，
					 * 則停損價換小*/
					boolean alread_out = false;
					if (it2.nextIndex() == barSet.size())
						continue; // 解決在資料尾端會造成 IndexOutOfBoundsException 的問題
					Bar newbar2 = barSet2.getBar(it2.nextIndex());
					if (newbar2.high >= basePrice2 + FORCE_STOPLOSS // 強制盤中停損
							&& !bull) { // 手上持有 short position
						int decide_force_out = -1;
						
						if (highestIndex(listHighOutForShort) == daysOutForShort - 1
							) {
							if (DEFAULT_START_OR_NOT[5] == true) {
								//應採"趨勢反轉出場"出場，且在開盤出場
								decide_force_out = 0;
							}
							else {
							  decide_force_out = 1;	
							}
						} 												
						else if (bar.close >= basePrice + lossStopForShort // 停損
								) {
							if (DEFAULT_START_OR_NOT[1] == true) {
								//空單停損，且在開盤出場
								decide_force_out = 0;
							}
							else {
								  decide_force_out = 1;	
							}
						}
						else if (bar.close <= basePrice - profitStopForShort) {  
							if (DEFAULT_START_OR_NOT[3] == true) {
								//空單停利，且在開盤出場
								decide_force_out = 0;	
							}
							else {
								decide_force_out = 1;	
							}
						}
						
						if (decide_force_out != 0){ //==0則選擇開盤出場							
							int original_force_stoploss = FORCE_STOPLOSS;
							if (decide_force_out == 1) {
								FORCE_STOPLOSS = HALF_FORCE_STOP_LOSS;
							}						
						
							forceOut = true;
							inHand = false; // 出場							
							this.numOutForceStopLoss++;
							prevTrade = "空單,強制盤中停損出場";
							int nextIndex = it.nextIndex();
							if (nextIndex == barSet.size())
								continue; // 解決在資料尾端會造成
											// IndexOutOfBoundsException 的問題
							double liquidatePrice2 = basePrice2
									+ FORCE_STOPLOSS;
							/**
							 * 開盤就要被強迫平倉了
							 */
							if (newbar2.open >= basePrice2 + FORCE_STOPLOSS) {
								liquidatePrice2 = newbar2.open;
							}
							else if (newbar2.high <= basePrice2 + FORCE_STOPLOSS)
							{ /*因為修改了FORCE_STOPLOSS值後，可能出現收盤出場也ok*/
									liquidatePrice2 = newbar2.close;									
							}
							Bar nextBar = barSet.getBar(nextIndex); // 交易
							// DATA_FILENAME
							Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
							// DATA_FILENAME2
							Bar breakBar2 = barSet.getBar(nextIndex - 1);

							double profit2 = basePrice2 - liquidatePrice2; // 計算獲利
							// accuProfit += profit;
							accuProfit += profit2;
							// scProfit.enter(profit);
							scProfit.enter(profit2);
							if (tradeDetailMap.containsKey(prevTrade)) {
								tradeDetailMap.get(prevTrade).enter(profit2);
							} else {
								StatCalc sc = new StatCalc();
								sc.enter(profit2);
								tradeDetailMap.put(prevTrade, sc);
							}
							stopForceStopLossStat.enter(profit2);
							// scProfitShort.enter(profit);
							scProfitShort.enter(profit2);

							if (IS_PRINT_TURTLE_SUMMARY) {
								scHoldCalendarDays.enter(diffCalendarDays(
										nextBar, baseBar));
								scHoldTransactionDays.enter(it.nextIndex()
										- baseBarIndex);
							}

							// printTurtleAction(nextBar, inHand, bull, profit,
							// daysOut,
							// true, lossStopForShort, liquidatePrice);
							printTurtleAction(nextBar, inHand, bull, false, profit2,
									daysOutForShort, false, -1, true,
									profitStopForShort, forceOut, false, false, 
									liquidatePrice2, nextBar2, breakBar2,
									scProfit);
							forceOut = false;
							alread_out = true;
							if (decide_force_out == 1) {
								FORCE_STOPLOSS = original_force_stoploss;
							}								
						}
					} else if (newbar2.low <= basePrice2 - FORCE_STOPLOSS // 強制盤中停損
							&& bull) { // 手上持有 多單
						int decide_force_out = -1;
						if (lowestIndex(listLowOutForLong) == daysOutForLong - 1
							) {
							if (DEFAULT_START_OR_NOT[4] == true) {
								//應採"趨勢反轉出場"出場，且在開盤出場
								decide_force_out = 0;
							}
							else {
							  decide_force_out = 1;	
							}
							
						} 												
						else if (bar.close <= basePrice - lossStopForLong // 停損
								&& bull) {
							if (DEFAULT_START_OR_NOT[0] == true) {
								//多單停損，且在開盤出場
								decide_force_out = 0;
							}
							else {
								  decide_force_out = 1;	
							}
						}
						else if (bar.close >= basePrice + profitStopForLong // 停利
									&& bull) {  
							if (DEFAULT_START_OR_NOT[2] == true) {
								//多單停利，且在開盤出場
								decide_force_out = 0;	
							}
							else {
								decide_force_out = 1;	
							}
						}
						
						if (decide_force_out != 0){ //==0則選擇開盤出場							
							int original_force_stoploss = FORCE_STOPLOSS;
							if (decide_force_out == 1) {
								FORCE_STOPLOSS = HALF_FORCE_STOP_LOSS;
							}
							
//							if (newbar2.today.get(Calendar.WEEK_OF_MONTH) == 3
//									&& newbar2.today.get(Calendar.DAY_OF_WEEK) == Calendar.THURSDAY) {
//								System.out.println("換倉日強迫出場");
//							}

							forceOut = true;
							inHand = false; // 出場							
							this.numOutForceStopLoss++;
							prevTrade = "多單,強制盤中停損出場";
							int nextIndex = it.nextIndex();
							if (nextIndex == barSet.size())
								continue; // 解決在資料尾端會造成
											// IndexOutOfBoundsException 的問題
							double liquidatePrice2 = basePrice2
									- FORCE_STOPLOSS;
							/**
							 * 開盤就要被強迫平倉了
							 */
							if (newbar2.open <= basePrice2 - FORCE_STOPLOSS) {
								liquidatePrice2 = newbar2.open;
							}
							else if (newbar2.low >= basePrice2 - FORCE_STOPLOSS)
							{ /*因為修改了FORCE_STOPLOSS值後，可能出現收盤出場也ok*/
									liquidatePrice2 = newbar2.close;									
							}
							
							Bar nextBar = barSet.getBar(nextIndex); // 交易
							// DATA_FILENAME
							Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
							// DATA_FILENAME2
							Bar breakBar2 = barSet.getBar(nextIndex - 1);

							double profit2 = liquidatePrice2 - basePrice2; // 計算獲利
							// accuProfit += profit;
							accuProfit += profit2;
							// scProfit.enter(profit);
							scProfit.enter(profit2);
							if (tradeDetailMap.containsKey(prevTrade)) {
								tradeDetailMap.get(prevTrade).enter(profit2);
							} else {
								StatCalc sc = new StatCalc();
								sc.enter(profit2);
								tradeDetailMap.put(prevTrade, sc);
							}
							stopForceStopLossStat.enter(profit2);

							scProfitLong.enter(profit2);

							if (IS_PRINT_TURTLE_SUMMARY) {
								scHoldCalendarDays.enter(diffCalendarDays(
										nextBar, baseBar));
								scHoldTransactionDays.enter(it.nextIndex()
										- baseBarIndex);
							}

							printTurtleAction(nextBar, inHand, bull, false, profit2,
									daysOutForShort, false, -1, true,
									profitStopForShort, forceOut, false, false, 
									liquidatePrice2, nextBar2, breakBar2,
									scProfit);
							forceOut = false;
							alread_out = true;
							if (decide_force_out == 1) {
								FORCE_STOPLOSS = original_force_stoploss;
							}							
						}
					}

					if (alread_out == true) {
						;
					} else if (listHighOutForShort.size() == daysOutForShort
							&& highestIndex(listHighOutForShort) == daysOutForShort - 1 
							&& !bull) { // 手上持有 short position
						inHand = false; // (空單)出場
						this.numOutTrendReverse++;
						prevTrade = "空單,趨勢反轉出場";
						
						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
						// 的問題

						Bar nextBar = barSet.getBar(nextIndex); // 交易
						// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);
						
						boolean startOrEnd = DEFAULT_START_OR_NOT[5];
						double liquidatePrice = startOrEnd ? nextBar.open:nextBar.close; // 假設隔天收盤價成交(多單平倉)
						double liquidatePrice2 = startOrEnd ? nextBar2.open:nextBar2.close; // 假設隔天收盤價成交(多單平倉)	
						
						/*實驗SVM*/
						
						if (this.useSVMModel[5]) {
						  startOrEnd = this.SVMSupport(barSet, barSet2, nextIndex, 5);
						  liquidatePrice2 = startOrEnd ? nextBar2.open: nextBar2.close;
						}
						
						double profit2 = basePrice2 - liquidatePrice2; // 計算獲利
						accuProfit += profit2;
						scProfit.enter(profit2);
						
						if (tradeDetailMap.containsKey(prevTrade)) {
							tradeDetailMap.get(prevTrade).enter(profit2);
						} else {
							StatCalc sc = new StatCalc();
							sc.enter(profit2);
							tradeDetailMap.put(prevTrade, sc);
						}
																					
						scProfitShort.enter(profit2);
						stopTrendReverseStat.enter(profit2);
						scHoldCalendarDays.enter(diffCalendarDays(nextBar,
								baseBar));
						scHoldTransactionDays.enter(it.nextIndex()
								- baseBarIndex);
						printTurtleAction(nextBar, inHand, bull, false, profit2,
								daysOutForShort, false, 0, false, -1, forceOut, false, startOrEnd,
								liquidatePrice2, nextBar2, breakBar2, scProfit);
						if ((this.useSVMModel[5]) && SUPPORT_OUT_INDAY && startOrEnd ==true) {
							  /*SVM建議開盤出場, 則反向入場一口多單*/					
							  printTurtleAddAction(nextBar, nextBar2, true, true, nextBar2.open, 
									  false,false, true, -1, bar,scSVMSellStrategyProfit);			      
							  scSVMSellStrategyProfit.enter(nextBar2.close -nextBar2.open);
							  stopProfitSVMIn4LongStat.enter(nextBar2.close -nextBar2.open);
						      printTurtleAddAction(nextBar, nextBar2, false,  true, nextBar2.close, 
						    		  false,false, true, nextBar2.close -nextBar2.open, bar,scSVMSellStrategyProfit);					      
						}										
					} else if (listLowOutForLong.size() == daysOutForLong
							&& lowestIndex(listLowOutForLong) == daysOutForLong - 1 
							&& bull) { // 手上持有 long position
						inHand = false; // 出場
						this.numOutTrendReverse++;
						prevTrade = "多單,趨勢反轉出場";
						
						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
						// 的問題

						Bar nextBar = barSet.getBar(nextIndex); // 交易
						// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						boolean startOrEnd = DEFAULT_START_OR_NOT[4];
						double liquidatePrice = startOrEnd ? nextBar.open:nextBar.close; // 假設隔天收盤價成交(多單平倉)
						double liquidatePrice2 = startOrEnd ? nextBar2.open:nextBar2.close; // 假設隔天收盤價成交(多單平倉)	

						/*實驗SVM*/						
						if (this.useSVMModel[4]) {
						  startOrEnd = this.SVMSupport(barSet, barSet2, nextIndex, 4);
						  liquidatePrice2 = startOrEnd ? nextBar2.open: nextBar2.close;
						}
						
						double profit2 = liquidatePrice2 - basePrice2; // 計算獲利
						scProfit.enter(profit2);
						
						scProfitLong.enter(profit2);
						if (tradeDetailMap.containsKey(prevTrade)) {
							tradeDetailMap.get(prevTrade).enter(profit2);
						} else {
							StatCalc sc = new StatCalc();
							sc.enter(profit2);
							tradeDetailMap.put(prevTrade, sc);
						}
						
						// accuProfit += profit;
						accuProfit += profit2;
						stopTrendReverseStat.enter(profit2);
						scHoldCalendarDays.enter(diffCalendarDays(nextBar,
								baseBar));
						scHoldTransactionDays.enter(it.nextIndex()
								- baseBarIndex);
						printTurtleAction(nextBar, inHand, bull, false, profit2,
								daysOutForLong, false, 0, false, -1, forceOut, false,startOrEnd,
								liquidatePrice2, nextBar2, breakBar2, scProfit);


						if ((DEFAULT_OUT_INDAY || this.useSVMModel[4]) && SUPPORT_OUT_INDAY && startOrEnd ==true) {
						  /*SVM建議開盤出場, 則反向入場一口空單*/					
						  printTurtleAddAction(nextBar, nextBar2, true, false, nextBar2.open, 
								  false,false, true,-1, bar,scSVMSellStrategyProfit);			      
						  scSVMSellStrategyProfit.enter(nextBar2.open-nextBar2.close);
					      stopProfitSVMIn4ShortStat.enter(nextBar2.open-nextBar2.close);
					      printTurtleAddAction(nextBar, nextBar2, false, false, nextBar2.close, 
					    		  false,false, true,nextBar2.open-nextBar2.close, bar,scSVMSellStrategyProfit);					      
						}						
					} else if (bar.close >= basePrice + lossStopForShort // 停損
							&& !bull) { // 手上持有 short position = 做空
						inHand = false; // 出場
						this.numOutStopLoss++;
						prevTrade = "空單,停損出場";
						
						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
						// 的問題

						Bar nextBar = barSet.getBar(nextIndex); // 交易
						// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						stopLossOpenCloseStat
								.enter(-(nextBar2.close - nextBar2.open));
						double temp2 = nextBar2.open - nextBar2.close; // *********
						accuProfit += temp2;
						scProfitShortCloseDayTrade.enter(temp2);
						/*實驗SVM*/
						boolean startOrEnd = DEFAULT_START_OR_NOT[1];
						double liquidatePrice = startOrEnd ? nextBar.open:nextBar.close; // 假設隔天收盤價成交(多單平倉)
						double liquidatePrice2 = startOrEnd ? nextBar2.open:nextBar2.close; // 假設隔天收盤價成交(多單平倉)	
						
						if (this.useSVMModel[1]) {
						  startOrEnd = this.SVMSupport(barSet, barSet2, nextIndex, 1);
  					      liquidatePrice2 = startOrEnd ? nextBar2.open: nextBar2.close;
						}
						
						double profit2 = basePrice2 - liquidatePrice2; // 計算獲利
						accuProfit += profit2;
						stopLossStat.enter(profit2);
						if (tradeDetailMap.containsKey(prevTrade)) {
							tradeDetailMap.get(prevTrade).enter(profit2);
						} else {
							StatCalc sc = new StatCalc();
							sc.enter(profit2);
							tradeDetailMap.put(prevTrade, sc);
						}
						scProfit.enter(profit2);
						
						/*嘗試在停損訊號出場當天同向進場*/
						{
							scProfitStopLossDoubleIn.enter(nextBar2.open - nextBar2.close);
							if (nextBar2.high-bar2.close > HALF_FORCE_STOP_LOSS)
							{
								scProfitStopLossPrevDoubleIn.enter(-HALF_FORCE_STOP_LOSS);
							}
							else {
								scProfitStopLossPrevDoubleIn.enter(bar2.close - nextBar2.close);
							}
						}
						
						// scProfitShort.enter(profit);
						scProfitShort.enter(profit2);
						if (profit2 >100000) { 
							/*不論現在損益，只要下一單是隔天且同向多單，則續抱*/
							/*這為空單則會賠!!!,所以空單停損不考慮留單*/
							tryContinueTrade = true; /*可試著保有單*/
							prevStopLossAndBull = 0;
						}
						else {
							  tryContinueTrade = false; 
						}
							
						
						if (IS_PRINT_TURTLE_SUMMARY) {
							scHoldCalendarDays.enter(diffCalendarDays(nextBar,
									baseBar));
							scHoldTransactionDays.enter(it.nextIndex()
									- baseBarIndex);
						}

						printTurtleAction(nextBar, inHand, bull, false, profit2,
								daysOutForShort, true, lossStopForShort, false,
								-1, forceOut, false, startOrEnd, liquidatePrice2, nextBar2,
								breakBar2, scProfit);


						if (this.useSVMModel[1] && SUPPORT_OUT_INDAY && startOrEnd ==true) {
						  /*SVM建議開盤出場, 則反向入場一口多單*/					
						  printTurtleAddAction(nextBar, nextBar2, true, true, nextBar2.open, 
								  false,true, false, -1, bar,scSVMSellStrategyProfit);			      
						  scSVMSellStrategyProfit.enter(nextBar2.close -nextBar2.open);
						  stopProfitSVMIn4LongStat.enter(nextBar2.close -nextBar2.open);
					      printTurtleAddAction(nextBar, nextBar2, false,  true, nextBar2.close, 
					    		  false,true, false, nextBar2.close -nextBar2.open, bar,scSVMSellStrategyProfit);					      
						}
					} else if (bar.close <= basePrice - lossStopForLong // 停損
							&& bull) { // 手上持有 long position = 做多
						inHand = false; // 出場
						this.numOutStopLoss++;
						prevTrade = "多單,停損出場";

						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
						// 的問題

						Bar nextBar = barSet.getBar(nextIndex); // 交易
						// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						stopLossOpenCloseStat.enter(nextBar2.close
								- nextBar2.open);

						accuProfit += (nextBar2.close - nextBar2.open); // *********
						// 停損多單平倉訊號指示出場當天，開盤加碼做多，收盤平倉所有部位 *************** 沒賺頭
						scProfitLongCloseDayTrade.enter(nextBar2.close
								- nextBar2.open);


						/*實驗SVM*/
						boolean startOrEnd = DEFAULT_START_OR_NOT[0];
						double liquidatePrice = startOrEnd ? nextBar.open:nextBar.close; // 假設隔天收盤價成交(多單平倉)
						double liquidatePrice2 = startOrEnd ? nextBar2.open:nextBar2.close; // 假設隔天收盤價成交(多單平倉)	
						
						if (this.useSVMModel[0]) {
						  startOrEnd = this.SVMSupport(barSet, barSet2, nextIndex, 0);
						  liquidatePrice2 = startOrEnd ? nextBar2.open: nextBar2.close;
						}
						
						double profit2 = liquidatePrice2 - basePrice2; // 計算獲利
						
						// accuProfit += profit;
						accuProfit += profit2;
						stopLossStat.enter(profit2);
						if (tradeDetailMap.containsKey(prevTrade)) {
							tradeDetailMap.get(prevTrade).enter(profit2);
						} else {
							StatCalc sc = new StatCalc();
							sc.enter(profit2);
							tradeDetailMap.put(prevTrade, sc);
						}
						scProfit.enter(profit2);
						
						/*嘗試在停損訊號出場當天同向進場*/
						{
							scProfitStopLossDoubleIn.enter(nextBar2.close - nextBar2.open); 
							if (bar2.close - nextBar2.low > HALF_FORCE_STOP_LOSS)
							{
								scProfitStopLossPrevDoubleIn.enter(-HALF_FORCE_STOP_LOSS);
							}
							else {
								scProfitStopLossPrevDoubleIn.enter(nextBar2.close-bar2.close);
							}
						}			
						
						scProfitLong.enter(profit2);

						if (startOrEnd==false  && profit2 >-10000) { /*不論現在損益，只要下一單是隔天且同向多單，則續抱*/
						  /*這十年來多一千多點!!!*/
						  tryContinueTrade = true; /*可試著保有單*/
						  prevStopLossAndBull = 1;
					    }
						else {
						  tryContinueTrade = false; 
						}
						
						if (IS_PRINT_TURTLE_SUMMARY) {
							scHoldCalendarDays.enter(diffCalendarDays(nextBar,
									baseBar));
							scHoldTransactionDays.enter(it.nextIndex()
									- baseBarIndex);
						}

						printTurtleAction(nextBar, inHand, bull, false, profit2,
								daysOutForLong, true, lossStopForLong, false,
								-1, forceOut, false,startOrEnd, liquidatePrice2, nextBar2,
								breakBar2, scProfit);

						if (this.useSVMModel[0] && SUPPORT_OUT_INDAY && startOrEnd ==true) {
						  /*SVM建議開盤出場, 則反向入場一口空單*/					
						  printTurtleAddAction(nextBar, nextBar2, true, false, nextBar2.open, 
						    		  false, true, false, -1, bar,scSVMSellStrategyProfit);			      
						  scSVMSellStrategyProfit.enter(nextBar2.open-nextBar2.close);
					      stopProfitSVMIn4ShortStat.enter(nextBar2.open-nextBar2.close);
					      printTurtleAddAction(nextBar, nextBar2, false, false, nextBar2.close, 
					    		  false, true, false, nextBar2.open-nextBar2.close, bar,scSVMSellStrategyProfit);					      
						}												
					}

					else if (bar.close <= basePrice - profitStopForShort // 停利
							&& !bull) { // 手上持有 short position = 做空
						inHand = false; // 出場
						this.numOutStopProfit++;
						prevTrade = "空單,停利出場";
						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
						// 的問題

						Bar nextBar = barSet.getBar(nextIndex); // 交易
						// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						/*實驗SVM*/
						boolean startOrEnd = DEFAULT_START_OR_NOT[3];
						double liquidatePrice = startOrEnd ? nextBar.open:nextBar.close; // 假設隔天收盤價成交(多單平倉)
						double liquidatePrice2 = startOrEnd ? nextBar2.open:nextBar2.close; // 假設隔天收盤價成交(多單平倉)	
						
						if (this.useSVMModel[3]) {
							startOrEnd = this.SVMSupport(barSet, barSet2, nextIndex, 3);
							liquidatePrice2 = startOrEnd ? nextBar2.open: nextBar2.close;
						}
						
						double profit2 = basePrice2 - liquidatePrice2; // 計算獲利
						stopProfitOpenCloseStat
								.enter(-(nextBar2.open - nextBar2.close));
						// accuProfit += profit;
						accuProfit += profit2;
						stopProfitStat.enter(profit2);
						scProfit.enter(profit2);		
						
						if (tradeDetailMap.containsKey(prevTrade)) {
							tradeDetailMap.get(prevTrade).enter(profit2);
						} else {
							StatCalc sc = new StatCalc();
							sc.enter(profit2);
							tradeDetailMap.put(prevTrade, sc);
						}
						scProfitShort.enter(profit2);

						if (IS_PRINT_TURTLE_SUMMARY) {
							scHoldCalendarDays.enter(diffCalendarDays(nextBar,
									baseBar));
							scHoldTransactionDays.enter(it.nextIndex()
									- baseBarIndex);
						}

						printTurtleAction(nextBar, inHand, bull, false, profit2,
								daysOutForShort, false, -1, true,
								profitStopForShort, forceOut, false,startOrEnd, liquidatePrice2,
								nextBar2, breakBar2, scProfit);

						if ((DEFAULT_OUT_INDAY || this.useSVMModel[3]) && SUPPORT_OUT_INDAY && startOrEnd ==true) {
						  /*SVM建議開盤出場, 則反向入場一口多單*/					
						  printTurtleAddAction(nextBar, nextBar2, true, true, nextBar2.open, 
						    		  true,false, false, -1, bar,scSVMSellStrategyProfit);			      
						  scSVMSellStrategyProfit.enter(nextBar2.close -nextBar2.open);
						  stopProfitSVMIn4LongStat.enter(nextBar2.close -nextBar2.open);
					      printTurtleAddAction(nextBar, nextBar2, false,  true, nextBar2.close, 
					    		  true,false, false, nextBar2.close -nextBar2.open, bar,scSVMSellStrategyProfit);					      
						}
												
					} else if (bar.close >= basePrice + profitStopForLong // 停利
							&& bull) { // 手上持有 long position = 做多
						inHand = false; // 出場
						this.numOutStopProfit++;
						prevTrade = "多單,停利出場";
						int nextIndex = it.nextIndex();
						if (nextIndex == barSet.size())
							continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
						// 的問題

						Bar nextBar = barSet.getBar(nextIndex); // 交易
						// DATA_FILENAME
						Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
						// DATA_FILENAME2
						Bar breakBar2 = barSet.getBar(nextIndex - 1);

						/*實驗SVM*/
						boolean startOrEnd = DEFAULT_START_OR_NOT[2];
						double liquidatePrice = startOrEnd ? nextBar.open:nextBar.close; // 假設隔天收盤價成交(多單平倉)
						double liquidatePrice2 = startOrEnd ? nextBar2.open:nextBar2.close; // 假設隔天收盤價成交(多單平倉)																	
												
						
						if (this.useSVMModel[2]) {
							startOrEnd = this.SVMSupport(barSet, barSet2, nextIndex, 2);
							liquidatePrice2 = startOrEnd ? nextBar2.open: nextBar2.close;
						}						
						
						double profit2 = liquidatePrice2 - basePrice2; // 計算獲利
						// accuProfit += profit;
						stopProfit4BullOpenCloseStat.enter(nextBar2.close- nextBar2.open);
						accuProfit += profit2;
						stopProfitStat.enter(profit2);
						

						if (tradeDetailMap.containsKey(prevTrade)) {
							tradeDetailMap.get(prevTrade).enter(profit2);
						} else {
							StatCalc sc = new StatCalc();
							sc.enter(profit2);
							tradeDetailMap.put(prevTrade, sc);
						}
						
						scProfit.enter(profit2);
						
						scProfitLong.enter(profit2);

						if (IS_PRINT_TURTLE_SUMMARY) {
							scHoldCalendarDays.enter(diffCalendarDays(nextBar,
									baseBar));
							scHoldTransactionDays.enter(it.nextIndex()
									- baseBarIndex);
						}

						printTurtleAction(nextBar, inHand, bull, false, profit2,
								daysOutForLong, false, -1, true,
								profitStopForLong, forceOut, false, startOrEnd, liquidatePrice2,
								nextBar2, breakBar2, scProfit);

						if (this.useSVMModel[2] && SUPPORT_OUT_INDAY && startOrEnd ==true) {
						  /*SVM建議開盤出場, 則反向入場一口空單*/					
						  printTurtleAddAction(nextBar, nextBar2, true, false, nextBar2.open, 
						    		  true,false, false,-1, bar,scSVMSellStrategyProfit);			      
						  scSVMSellStrategyProfit.enter(nextBar2.open-nextBar2.close);
					      stopProfitSVMIn4ShortStat.enter(nextBar2.open-nextBar2.close);
					      printTurtleAddAction(nextBar, nextBar2, false, false, nextBar2.close, 
					    		  true,false, false,nextBar2.open-nextBar2.close, bar,scSVMSellStrategyProfit);					      
						}						
					}
					else { /*都未出場,則考慮一下如何確保獲利*/
						if (dayInHand > MAX_DAY_INHAND) { /*這一單握太久*/
							double curPro = bull ? bar2.close - basePrice2 : basePrice2 - bar2.close ;  /*現階段獲利*/
							if (maxProfitOneTrade > 0 && curPro>maxProfitOneTrade * MAX_KEEP_INHAND_PERCENTAGE)
							{
							    /*選擇出場,以確保獲利*/
								
								inHand = false; // 出場
								this.numOutKeepProfit++;
								prevTrade = bull? "多單,保持獲利出場" : "空單,保持獲利出場";
								
								int nextIndex = it.nextIndex();
								if (nextIndex == barSet.size())
									continue; // 解決在資料尾端會造成 IndexOutOfBoundsException
								// 的問題

								Bar nextBar = barSet.getBar(nextIndex); // 交易
								// DATA_FILENAME
								Bar nextBar2 = barSet2.getBar(nextIndex); // 交易
								// DATA_FILENAME2
								Bar breakBar2 = barSet.getBar(nextIndex - 1);

								double liquidatePrice = nextBar.open; // 假設隔天收盤價成交(多單平倉)
								double liquidatePrice2 = nextBar2.open; // 假設隔天收盤價成交(多單平倉)

								double profit2 = bull ? liquidatePrice2 - basePrice2 : basePrice2 - liquidatePrice2; // 計算獲利
								accuProfit += profit2;
								keepProfitStat.enter(profit2);
								if (tradeDetailMap.containsKey(prevTrade)) {
									tradeDetailMap.get(prevTrade).enter(profit2);
								} else {
									StatCalc sc = new StatCalc();
									sc.enter(profit2);
									tradeDetailMap.put(prevTrade, sc);
								}
								// scProfit.enter(profit);
								scProfit.enter(profit2);
								// scProfitLong.enter(profit);
								if (bull)
									scProfitLong.enter(profit2);
								else
									scProfitShort.enter(profit2);

								if (IS_PRINT_TURTLE_SUMMARY) {
									scHoldCalendarDays.enter(diffCalendarDays(nextBar,
											baseBar));
									scHoldTransactionDays.enter(it.nextIndex()
											- baseBarIndex);
								}
								
								printTurtleAction(nextBar, inHand, bull, false, profit2,
										daysOutForLong, false, -1, true,
										profitStopForLong, forceOut, true, true, liquidatePrice2,
										nextBar2, breakBar2, scProfit);								
							}
						}						
					}
				}

				if (inHand) {
					dayInHand++;
				}
				else {
					maxProfitOneTrade = 0;
					dayInHand = 0;
				}
			}
		}

		StringBuffer buf = new StringBuffer();
		String line;
		if (IS_PRINT_TURTLE_SUMMARY) {
			setAcc(scProfit.getSum());
			setProfitStat(scProfit);
			setMDD(scProfit.maxDrawDown);
			line = String
					.format(
							"acc=%.0f[多%d進,%d出][空%d進,%d出][停損%d,%d][停利%d,%d][強制盤中停損%d],%d筆交易(%dW/%dL,勝率%.3f),\nave持有天數=%.1f(共 %.0f)日曆天=%.1f(共 %.0f)交易日,ave每筆交易獲利=%.1f(%.1fW/%.1fL),\nmin持有天數=%.0f日曆天=%.0f交易日,max持有天數=%.0f日曆天=%.0f交易日,\nmax單筆獲利=%.0f,min單筆獲利=%.0f,持有天數std=%.1f日曆天=%.1f交易日,單筆獲利std=%.1f",
							scProfit.getSum(), daysInForLong, daysOutForLong,
							daysInForShort, daysOutForShort, lossStopForLong,
							lossStopForShort, profitStopForLong,
							profitStopForShort, FORCE_STOPLOSS,
							scHoldCalendarDays.getCount(), scProfit
									.getPositiveCount(), scProfit
									.getNegativeCount(), (scProfit
									.getPositiveCount() + 0.0)
									/ scProfit.getCount(), scHoldCalendarDays
									.getMean(), scHoldCalendarDays.getSum(),
							scHoldTransactionDays.getMean(),
							scHoldTransactionDays.getSum(), scProfit.getMean(),
							scProfit.getPositiveMean(), scProfit
									.getNegativeMean(), scHoldCalendarDays
									.getMin(), scHoldTransactionDays.getMin(),
							scHoldCalendarDays.getMax(), scHoldTransactionDays
									.getMax(), scProfit.getMax(), scProfit
									.getMin(), scHoldCalendarDays
									.getStandardDeviation(),
							scHoldTransactionDays.getStandardDeviation(),
							scProfit.getStandardDeviation());
			buf.append(line + "\n");
			line = String.format("獲利單之平均獲利:%.1f,虧損單之平均虧損:%.1f",scProfit.getPositiveMean(),scProfit.getNegativeMean());
			buf.append(line + "\n");
			// System.out.println(line);
			line = "出場條件:" + this.numOutTrendReverse + "次趨勢反轉出場(max="
					+ stopTrendReverseStat.getMax() + ",min="
					+ stopTrendReverseStat.getMin() + ",正獲利次數="
					+ stopTrendReverseStat.getPositiveCount() + "(平均"
					+ (int) stopTrendReverseStat.getPositiveMean() + "),負獲利次數="
					+ stopTrendReverseStat.getNegativeCount() + "(平均"
					+ (int) stopTrendReverseStat.getNegativeMean() + "))\n"
					+ "出場條件:" + this.numOutStopLoss + "次停損出場(max="
					+ stopLossStat.getMax() + ",min=" + stopLossStat.getMin()
					+ ",正獲利次數=" + stopLossStat.getPositiveCount() + "(平均"
					+ (int) stopLossStat.getPositiveMean() + "),負獲利次數="
					+ stopLossStat.getNegativeCount() + "(平均"
					+ (int) stopLossStat.getNegativeMean() + "))\n" + "出場條件:"
					+ this.numOutStopProfit + "次停利出場(max="
					+ stopProfitStat.getMax() + ",min="
					+ stopProfitStat.getMin() + ",正獲利次數="
					+ stopProfitStat.getPositiveCount() + "(平均"
					+ (int) stopProfitStat.getPositiveMean() + "),負獲利次數="
					+ stopProfitStat.getNegativeCount() + "(平均"
					+ (int) stopProfitStat.getNegativeMean() + "))\n" + "出場條件:"
					+ this.numOutForceStopLoss + "次盤中停損出場(max="
					+ stopForceStopLossStat.getMax() + ",min="
					+ stopForceStopLossStat.getMin() + "(平均"
					+ (int) stopForceStopLossStat.getMean() + "))" + "\n";

			buf.append(line);

			line = String
			.format(
					"出場反向當沖進出場acc=%.0f,%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL)",
					scSVMSellStrategyProfit.getSum(), scSVMSellStrategyProfit.getCount(),scSVMSellStrategyProfit.getPositiveCount(),
					scSVMSellStrategyProfit.getNegativeCount(),scSVMSellStrategyProfit.getPositiveCount()/(double)scSVMSellStrategyProfit.getCount(),
					scSVMSellStrategyProfit.getMean(),scSVMSellStrategyProfit.getPositiveMean(),scSVMSellStrategyProfit.getNegativeMean());
	       buf.append(line + "\n");			

		  line = "    訊號為開盤出場時,反向當沖空單進場,好處:(去頭尾)平均" +
		            stopProfitSVMIn4ShortStat.getTruncatedMean()+
		  		    "最大獲利:"
					+ stopProfitSVMIn4ShortStat.getMax() + ",最大損失:"
					+ stopProfitSVMIn4ShortStat.getMin() + ",獲利次數:"
					+ stopProfitSVMIn4ShortStat.getPositiveCount() + "(平均"
					+ stopProfitSVMIn4ShortStat.getPositiveMean() + "),損失次數:"
					+ stopProfitSVMIn4ShortStat.getNegativeCount() + "(平均"
					+ stopProfitSVMIn4ShortStat.getNegativeMean() + ")";
		  buf.append(line + "\n");		   
		  line = "    訊號為開盤出場時,反向當沖多單進場,好處:(去頭尾)平均" +
		             stopProfitSVMIn4LongStat.getTruncatedMean()+
		  		    "最大獲利:"
				+ stopProfitSVMIn4LongStat.getMax() + ",最大損失:"
				+ stopProfitSVMIn4LongStat.getMin() + ",獲利次數:"
				+ stopProfitSVMIn4LongStat.getPositiveCount() + "(平均"
				+ stopProfitSVMIn4LongStat.getPositiveMean() + "),損失次數:"
				+ stopProfitSVMIn4LongStat.getNegativeCount() + "(平均"
				+ stopProfitSVMIn4LongStat.getNegativeMean() + ")";
		   buf.append(line + "\n");
		   
			line = String
			.format(
					"(DoubleIn)停損出場訊號(收盤出場)出現,當日同向當沖進出場(強制停損設定%d點)acc=%.0f,%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL), 單筆Max=%.1f, Min=%.1f",
					this.HALF_FORCE_STOP_LOSS,
					scProfitStopLossDoubleIn.getSum(), scProfitStopLossDoubleIn.getCount(),scProfitStopLossDoubleIn.getPositiveCount(),
					scProfitStopLossDoubleIn.getNegativeCount(),scProfitStopLossDoubleIn.getPositiveCount()/(double)scProfitStopLossDoubleIn.getCount(),
					scProfitStopLossDoubleIn.getMean(),scProfitStopLossDoubleIn.getPositiveMean(),scProfitStopLossDoubleIn.getNegativeMean(),
					scProfitStopLossDoubleIn.getMax(),scProfitStopLossDoubleIn.getMin());
	       buf.append(line + "\n");					   
		   
			line = String
			.format(
					"(DoubleIn)停損出場訊號(收盤出場)出現,昨日收盤同向進場,訊號當日收盤出場(強制停損設定%d點)acc=%.0f,%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL), 單筆Max=%.1f, Min=%.1f",
					this.HALF_FORCE_STOP_LOSS,
					scProfitStopLossPrevDoubleIn.getSum(), scProfitStopLossPrevDoubleIn.getCount(),scProfitStopLossPrevDoubleIn.getPositiveCount(),
					scProfitStopLossPrevDoubleIn.getNegativeCount(),scProfitStopLossPrevDoubleIn.getPositiveCount()/(double)scProfitStopLossPrevDoubleIn.getCount(),
					scProfitStopLossPrevDoubleIn.getMean(),scProfitStopLossPrevDoubleIn.getPositiveMean(),scProfitStopLossPrevDoubleIn.getNegativeMean(),
					scProfitStopLossPrevDoubleIn.getMax(),scProfitStopLossPrevDoubleIn.getMin());
	       buf.append(line + "\n");				
	       
			line = (String
					.format(
							"(DoubleIn)多單建立日，開盤多一多單入場，收盤當沖出場(強制停損設定%d點)=%.0f ,共%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL),max單筆獲利=%.0f,min單筆獲利=%.0f,單筆獲利std=%.1f",
							this.HALF_FORCE_STOP_LOSS,
							scProfitLongDayTrade.getSum(), scProfitLongDayTrade
									.getCount(), scProfitLongDayTrade
									.getPositiveCount(), scProfitLongDayTrade
									.getNegativeCount(), (scProfitLongDayTrade
									.getPositiveCount() + 0.0)
									/ scProfitLongDayTrade.getCount(),
							scProfitLongDayTrade.getMean(),
							scProfitLongDayTrade.getPositiveMean(),
							scProfitLongDayTrade.getNegativeMean(),
							scProfitLongDayTrade.getMax(), scProfitLongDayTrade
									.getMin(), scProfitLongDayTrade
									.getStandardDeviation()));
			buf.append(line + "\n");	 
			line = (String
					.format(
							"(DoubleIn)空單建立前日，收盤多一空單入場，收盤當沖出場(強制停損設定%d點)=%.0f ,共%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL),max單筆獲利=%.0f,min單筆獲利=%.0f,單筆獲利std=%.1f",
							this.HALF_FORCE_STOP_LOSS,
							scProfitShortDayTrade.getSum(), scProfitShortDayTrade
									.getCount(), scProfitShortDayTrade
									.getPositiveCount(), scProfitShortDayTrade
									.getNegativeCount(), (scProfitShortDayTrade
									.getPositiveCount() + 0.0)
									/ scProfitShortDayTrade.getCount(),
									scProfitShortDayTrade.getMean(),
									scProfitShortDayTrade.getPositiveMean(),
									scProfitShortDayTrade.getNegativeMean(),
									scProfitShortDayTrade.getMax(), scProfitShortDayTrade
									.getMin(), scProfitShortDayTrade
									.getStandardDeviation()));
			buf.append(line + "\n");
			
	       
			Iterator<String> iter = tradeMap.keySet().iterator();
			while (iter.hasNext()) {
				String key = iter.next();
				line = key + "個數:" + tradeMap.get(key) + "\n";
				buf.append(line);
			}
			iter = tradeDetailMap.keySet().iterator();
			while (iter.hasNext()) {
				String key = iter.next();
				line = tradeDetailMap.get(key).getCount() + "次" + key + " ("
						+ tradeDetailMap.get(key).getPositiveCount() + "W/"
						+ tradeDetailMap.get(key).getNegativeCount() + "L)"
						+ " 獲利: 平均=" + (int) tradeDetailMap.get(key).getMean()
						+ ",max=" + (int) tradeDetailMap.get(key).getMax()
						+ ",min=" + (int) tradeDetailMap.get(key).getMin()
						+ "\n";
				buf.append(line);
			}
			line = (String
					.format(
							"多單accLong獲利=%.0f ,共%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL),max單筆獲利=%.0f,min單筆獲利=%.0f,單筆獲利std=%.1f",
							scProfitLong.getSum(), scProfitLong.getCount(),
							scProfitLong.getPositiveCount(), scProfitLong
									.getNegativeCount(), (scProfitLong
									.getPositiveCount() + 0.0)
									/ scProfitLong.getCount(), scProfitLong
									.getMean(), scProfitLong.getPositiveMean(),
							scProfitLong.getNegativeMean(), scProfitLong
									.getMax(), scProfitLong.getMin(),
							scProfitLong.getStandardDeviation()));
			buf.append(line + "\n");
			// System.out.println(line);

			line = (String
					.format(
							"空單accShort獲利=%.0f ,共%d筆交易(%dW/%dL,勝率%.3f),ave每筆交易獲利=%.1f(%.1fW/%.1fL),max單筆獲利=%.0f,min單筆獲利=%.0f,單筆獲利std=%.1f",
							scProfitShort.getSum(), scProfitShort.getCount(),
							scProfitShort.getPositiveCount(), scProfitShort
									.getNegativeCount(), (scProfitShort
									.getPositiveCount() + 0.0)
									/ scProfitShort.getCount(), scProfitShort
									.getMean(),
							scProfitShort.getPositiveMean(), scProfitShort
									.getNegativeMean(), scProfitShort.getMax(),
							scProfitShort.getMin(), scProfitShort
									.getStandardDeviation()));
			buf.append(line + "\n");

			logger.info("\n" + buf.toString());
			summary = buf.toString();
		}
		if (trainSVM) {
		  for (int i=0;i<svmAllCount.length;i++) {
			System.out.println(
					(String.format("[%d,%d]:%.3f",
					svmAllCount[i],svmPositiveCount[i], svmPositiveCount[i]/(double)svmAllCount[i])));
		  }
		}
		return scProfit.getSum();
	}

	private static Logger loadDefaultLogger() {
		Properties logp = new Properties();
		try {
			logp.load(PriceData.class.getClassLoader().getResourceAsStream(
					"turtle/system/pt/j4util.properties"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		PropertyConfigurator.configure(logp);

		return Logger.getRootLogger();
	}

	/**
	 * return sell in 開盤or not
	 * @param barSet
	 * @param barSet2
	 * @param nextIndex
	 * @param sellType
	 * @return
	 */
	public boolean SVMSupport(BarSet barSet, BarSet barSet2, int nextIndex, int sellType) {
		/*實驗SVM*/		
		if (useSVM) {			
			try {
				BufferedWriter writer = new BufferedWriter(new FileWriter("tmp/svm_orig.tmp"));
				BufferedWriter writer1 = new BufferedWriter(new FileWriter("tmp/svm_scaled.tmp"));
				
				svm_scale scaler = new svm_scale();

				String[] sarg = new String[] {"-r",svmFilePrefix[sellType]+scaleSVMFileSuffix, "tmp/svm_orig.tmp"};
				String[] parg = new String[] {"tmp/svm_scaled.tmp", svmFilePrefix[sellType]+modelSVMFileSuffix, "tmp/svm_out.tmp"};																

				StringBuffer buf  = new StringBuffer();

				Bar yesyesBar = barSet.getBar(nextIndex-3);
				Bar yesyesBar2 = barSet2.getBar(nextIndex-3);
				
				Bar yesBar = barSet.getBar(nextIndex-2);
				Bar yesBar2 = barSet2.getBar(nextIndex-2);
				
				Bar bar = barSet.getBar(nextIndex-1);
				Bar bar2 = barSet2.getBar(nextIndex-1);

				Bar nextBar = barSet.getBar(nextIndex);
				Bar nextBar2 = barSet2.getBar(nextIndex);

				
				buf.append("1");
				

				buf.append(" 1:"+ (String.format("%d", (bar2.open>bar2.close? 1:-1))));
				buf.append(" 2:"+ (String.format("%d", (yesBar2.open>yesBar2.close? 1:-1))));
				buf.append(" 3:"+ (String.format("%d", (yesyesBar2.open>yesyesBar2.close? 1:-1))));
				
				buf.append(" 4:"+ (String.format("%d", (bar2.open>yesBar2.open? 1:-1))));
				buf.append(" 5:"+ (String.format("%d", (bar2.close>yesBar2.close? 1:-1))));
				buf.append(" 6:"+ (String.format("%d", (bar2.high>yesBar2.high? 1:-1))));
				buf.append(" 7:"+ (String.format("%d", (bar2.low>yesBar2.low? 1:-1))));

				buf.append(" 8:"+ (String.format("%d", (bar2.open>yesBar2.close? 1:-1))));
				buf.append(" 9:"+ (String.format("%d", (bar2.close>yesBar2.open? 1:-1))));
							
				buf.append(" 10:"+ (String.format("%d", (bar.volume>yesBar.volume? 1:-1))));
				buf.append(" 11:"+ (String.format("%d", (yesBar.volume>yesyesBar.volume? 1:-1))));
				
				writer.write(buf.toString()+"\n");
				writer.close();
				
				String scaleOut = scaler.run(sarg);
				writer1.write(scaleOut+"\n");
				writer1.close();
				
				svm_predict.main(parg);
				BufferedReader reader = new BufferedReader(new FileReader("tmp/svm_out.tmp"));
				boolean ret = false;
				if ((int)Double.parseDouble(reader.readLine()) == 1) {
				    	ret = true;
				}
				else {
					ret = false;
				}
				reader.close();
				   
				   if (sellType == 1 || sellType == 3 || sellType == 5) { /*空單*/
					   if (nextBar2.open>nextBar2.close && ret ==true) {
						   //System.out.println("error");
					   }
					}
					else { /*多單*/
						   if (nextBar2.open>nextBar2.close && ret ==false) {
							   //System.out.println("error");
						   }
					}
				
				return ret;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}							
		}
		if (trainSVM) {
			StringBuffer buf  = new StringBuffer();
			Bar yesyesBar = barSet.getBar(nextIndex-3);
			Bar yesyesBar2 = barSet2.getBar(nextIndex-3);
			
			Bar yesBar = barSet.getBar(nextIndex-2);
			Bar yesBar2 = barSet2.getBar(nextIndex-2);
			boolean ret = false;
			Bar bar = barSet.getBar(nextIndex-1);
			Bar bar2 = barSet2.getBar(nextIndex-1);

			Bar nextBar = barSet.getBar(nextIndex);
			Bar nextBar2 = barSet2.getBar(nextIndex);
			svmAllCount[sellType]++;
			if (sellType == 1 || sellType == 3 || sellType == 5) { /*空單*/
			  buf.append(nextBar2.open<nextBar2.close-0?"1":"-1");
			  svmPositiveCount[sellType]+=nextBar2.open<nextBar2.close-0?1:0;
			  ret = nextBar2.open>nextBar2.close? false:true;
			}
			else { /*多單*/
			  buf.append(nextBar2.open>nextBar2.close+0?"1":"-1");
			  svmPositiveCount[sellType]+=nextBar2.open>nextBar2.close+0?1:0;
			  ret = nextBar2.open>nextBar2.close? true: false;
			}
			
			buf.append(" 1:"+ (String.format("%d", (bar2.open>bar2.close? 1:-1))));
			buf.append(" 2:"+ (String.format("%d", (yesBar2.open>yesBar2.close? 1:-1))));
			buf.append(" 3:"+ (String.format("%d", (yesyesBar2.open>yesyesBar2.close? 1:-1))));
			
			buf.append(" 4:"+ (String.format("%d", (bar2.open>yesBar2.open? 1:-1))));
			buf.append(" 5:"+ (String.format("%d", (bar2.close>yesBar2.close? 1:-1))));
			buf.append(" 6:"+ (String.format("%d", (bar2.high>yesBar2.high? 1:-1))));
			buf.append(" 7:"+ (String.format("%d", (bar2.low>yesBar2.low? 1:-1))));

			buf.append(" 8:"+ (String.format("%d", (bar2.open>yesBar2.close? 1:-1))));
			buf.append(" 9:"+ (String.format("%d", (bar2.close>yesBar2.open? 1:-1))));
						
			buf.append(" 10:"+ (String.format("%d", (bar.volume>yesBar.volume? 1:-1))));
			buf.append(" 11:"+ (String.format("%d", (yesBar.volume>yesyesBar.volume? 1:-1))));
			
			try {
				svmInput[sellType].append(buf.toString()+"\n");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return ret;
		}
		return false;
	}
	
	public static void main(String[] args) throws IOException {
		/**
		 * 使用新的資料
		 * 
		 */
		MAX_DAY_INHAND = 10000;
		MAX_KEEP_INHAND_PERCENTAGE = 0.99;
		LOSS_STOP_RANGE_FOR_LONG_CONSERVATIVE = new int[] { 30, 30 }; // 做多停損點數實驗區間
		PROFIT_STOP_RANGE_FOR_LONG_CONSERVATIVE = new int[] { 195, 195 }; // 做多停利點數實驗區間
		LOSS_STOP_RANGE_FOR_SHORT_CONSERVATIVE = new int[] { 55, 55 }; // 做空停損點數實驗區間
		PROFIT_STOP_RANGE_FOR_SHORT_CONSERVATIVE = new int[] { 170, 170 }; // 做空停利點數實驗區間
		inAndOut_CONSERVATIVE = new int[][] { // 特別觀察組合
				                            { 2, 9, 2, 5 } };
		PriceDataSVMSystem cons = new PriceDataSVMSystem(
				PriceDataSVMSystem.STRATEGY_CONSERVATIVE,
				DailyStopProfitExec.WTX0_PREFIX_FN
						+ DailyStopProfitExec.FN_SUFFIX,
				DailyStopProfitExec.WTX1_PREFIX_FN
						+ DailyStopProfitExec.FN_SUFFIX);

	}
}
